/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package au.com.gworks.jump.app.wiki.client;

import java.util.Map;

import org.javaongems.client.AbstractGemlet;
import org.javaongems.client.Controller;
import org.javaongems.client.Gem;
import org.javaongems.client.View;
import org.javaongems.client.rt.io.PathUtils;
import org.javaongems.client.service.ResourceBundleRpc.LocaleInfo;

import au.com.gworks.jump.app.wiki.client.service.WikiRpc;
import au.com.gworks.jump.app.wiki.client.service.WikiRpcAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;

public class Jump extends AbstractGemlet {
	final static public String JUMP_WIKI_SUBCTX_PROP = "jump.wiki.subctx";
	final static public String MYSPACES_CONTROLLER = "my-spaces.controller";

	final static private String SAMPLE_BUNDLE_NAME = "au.com.gworks.jump.app.wiki.resource.Sample";

	private DesktopPage 		view;
	private Alert.Controller	reporter;

	public void initialiseView() {
		isDebug = true;
		loadSampleResourceBundles();
		reporter = new Alert.Controller();
		reporter.setUp(null);
		view = new DesktopPage();
		view.show();
		openContext();
	}
	
	public ServiceDefTarget openService(String serviceName) {
		ServiceDefTarget ret = super.openService(serviceName);
		if (ret == null && WikiRpc.SERVICE_CTX.equals(serviceName)) 
			ret = initialiseWikiService();
	    return ret;
	}

	private ServiceDefTarget initialiseWikiService() {
		ServiceDefTarget ret;
		WikiRpcAsync async = (WikiRpcAsync) GWT.create(WikiRpc.class);
		ret = (ServiceDefTarget) async;
		String ctx = getApplCtx() + getGemsGwtRpcContext() + WikiRpc.SERVICE_CTX;
		ret.setServiceEntryPoint(ctx);
		setServiceInCache(WikiRpc.SERVICE_CTX, ret);
		return ret;
	}

	public void handleServiceFailures(Throwable caught) {
		String severeErrMsg = "Unable to load the browser environment. This is a fatal error. Please report this to your adminsitrators.\n";
		String msg = "";
    	if (caught instanceof WikiRpc.SystemFailureException) {
    		String rc = ((WikiRpc.SystemFailureException) caught).rootCauseStackTrace;
    		msg = severeErrMsg + rc;
    	} else if (caught instanceof WikiRpc.UnauthorisedAccessException) {
    		msg = "Sorry. Your credentials are insufficient to access/manipulate the following resource [" +
    		((WikiRpc.UnauthorisedAccessException)caught).requestedPath + "].";
    	} else if (caught instanceof WikiRpc.ResourceNotFoundException) {
    		WikiRpc.ResourceNotFoundException err = (WikiRpc.ResourceNotFoundException) caught;
    		String revMsg = err.resourcePath + " at (r" + err.revision + ")";
    		msg = "Sorry. Resource " + revMsg + " is not found on the system. [ash u need to put the broken links candidate selection dialog here instead]";
    	} else if (caught instanceof WikiRpc.CompilationException) {
    		WikiRpc.CompilationException err = (WikiRpc.CompilationException) caught;
    		msg = "Sorry. The wiki resource " + err.source.getAbsolutePath() + " encountered a compilation error. Please check the validity of the resource or contact the plugin vendor for support with the following trace information\n" +
    		err.rootCauseStackTrace;
    	} else {
    		msg = caught.getMessage();
    	}
		alertMessage(msg);
	}

	public void handlePageLoadFailureIfAny() {
		String exceptionClass = Gem.stone.getGemPropertyAsString("exceptionClass", null);
		if (exceptionClass == null)
			return;
		String msg = Gem.stone.getGemPropertyAsString("exceptionClass.message", null);
		if (msg == null || msg.equals(""))
			msg = "The system encountered an unexpected service failure, please try that action again";
		alertMessage(msg);
	}

	public void openParameterisedUrl(String[] args) {
		String namespace = args[0], revSpecifier = args[1], path = args[2];
		StringBuffer build = new StringBuffer(PathUtils.appendSlashIfRequired(getApplCtx()));
		build.append(PathUtils.appendSlashIfRequired(Gem.stone.getGemPropertyAsString(JUMP_WIKI_SUBCTX_PROP, "")));
		boolean noRev = (revSpecifier == null || "null".equals(revSpecifier) || "".equals(revSpecifier));
		if (noRev)
			build.append(namespace);
		else {
			build.append(PathUtils.appendSlashIfRequired(namespace));
			build.append(revSpecifier);
		}
		build.append(path);
		String uri = build.toString();
		Gem.stone.openUrl(uri);
	}

	public boolean isDebugEnabled() {
		return isDebug;
	}

	public void log(String msg, Throwable err) {
		jumpLog(msg);
		GWT.log(msg, err);
	}
	
	native private void jumpLog(String msg) /*-{
		$wnd.gemOutPrintln(msg);
	}-*/;

	public void reportStatus(String msg)  {
		reporter.reportStatus(msg);	
	}

	public void alertMessage(String msg) {
		reporter.alert(msg);
	}
	
	// application specific controller logic
	private void openContext() {
		String ctAsStr = (String) getGemProperty("contextType");
		if (ctAsStr == null)
			return;
		int ct = Integer.parseInt(ctAsStr);
		if (WikiRpc.OPEN_RESOURCE_CTX == ct)  
			return;
		else if (WikiRpc.EXPLORE_CTX == ct) 
			view.actionBar.launchExplorer();
	}
	
	protected void onResourceBundleFetched(String name, LocaleInfo locale, Map bundle) {
		if (Gem.stone.isDebugEnabled()) {
			String locAsStr = locale == null ? "": locale.toString();
			String hello = (String) bundle.get("hello");
			String goodbye = (String) bundle.get("goodbye");
			Gem.stone.log("bundle: " + name + "/" + locAsStr + "[" + hello + "," + goodbye + "]");
		}
	}
	
	private void loadSampleResourceBundles() {
		getResourceBundle(SAMPLE_BUNDLE_NAME, LocaleInfo.HTTP_REQUEST_LOCALE);
		getResourceBundle(SAMPLE_BUNDLE_NAME, new LocaleInfo("en", "AU", "slang"));
		getResourceBundle(SAMPLE_BUNDLE_NAME, new LocaleInfo("en", "SL"));
	}
	
	public class DesktopPage implements View {
		private ActionBar actionBar = new ActionBar();

		public DesktopPage() {
		    RootPanel.get("displayAreaActionBar").add(actionBar);
		    actionBar.initialise();
		}
		
		public Controller getController() 	{ return null; }
		public void show() 					{ 
			actionBar.load(); 
		}
		public void hide() 					{ /*do nothing*/ }
		public void refresh() {
			// this can be to re-request the page from the server
			// this will loose all state
		}
		public void open() 					{ /*do nothing*/ }
		public void close() 				{ /*do nothing*/ }
	}
}